/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.core.action.retrieve;

import com.inspur.edp.bef.api.be.IBEContext;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveParam;
import com.inspur.edp.bef.core.be.BEContext;
import com.inspur.edp.bef.core.lock.LockService;
import com.inspur.edp.bef.core.lock.LockUtils;
import com.inspur.edp.bef.core.scope.ScopeNodeParameter;
import com.inspur.edp.bef.core.scope.SingleBETypeExtension;
import com.inspur.edp.cef.api.repository.IRootRepository;
import com.inspur.edp.cef.entity.condition.EntityFilter;
import com.inspur.edp.cef.entity.condition.NodeSortInfo;
import com.inspur.edp.cef.entity.condition.RetrieveFilter;
import com.inspur.edp.cef.entity.entity.IEntityData;
import java.util.List;
import java.util.stream.Collectors;

public class RetrieveExtension extends SingleBETypeExtension<RetrieveScopeNodeParameter> {

   // region Constructor

   public RetrieveExtension() {
      super();
   }

   // endregion

   // region 属性字段

   // endregion

   @Override
   public void onExtendSetComplete() {
      IBEContext context=null;
      if (getBEParameters() != null && getBEParameters().size() > 0) {
         context = getBEParameters().get(0).getBEContext();
      }
      if(LockUtils.needLock(context.getModelResInfo())) {
         List<String> idList = getBEParameters().stream()
             .filter(par -> par.getParam().getNeedLock())
             .map(a -> a.getBEContext().getID())
             .collect(Collectors.toList());
         if (!idList.isEmpty()) {
            addLock(idList);
         }
      }

      // ① 批量获取；
      java.util.HashMap<String, IEntityData> dic = multiRetrieveFromDAL();
      // ② 执行回调函数；
      executeAction(dic);
   }

   /**
    * 调用回调函数
    */
   private void executeAction(java.util.HashMap<String, IEntityData> dicData) {
      // 无论是否返回检索结果，一定调用回调函数，未返回则赋值null
      for (RetrieveScopeNodeParameter item : getBEParameters()) {
         IEntityData data = dicData.get(item.getBEContext().getID());
         item.executeAction(item.getBEContext(), data);
      }
   }

   /**DAL批量Retriev */
   private java.util.HashMap<String, IEntityData> multiRetrieveFromDAL() {
      List<String> idList =
          getBEParameters().stream().map(a -> a.getBEContext().getID()).collect(Collectors.toList());
      IRootRepository repository = ((BEContext) getBEParameters().get(0).getBEContext())
          .getSessionItem().getBEManager().getRepository();

      RetrieveFilter retrieveFilter = null;
      if (!getBEParameters().isEmpty()) {
         RetrieveParam param = (getBEParameters().get(0)).getParam();
         if (param != null) {
            retrieveFilter = param.getRetrieveFilter();
         }
         combineSortInfo(retrieveFilter, param);
      }
      List<IEntityData> result = repository.retrieve(idList, retrieveFilter);

      java.util.HashMap<String, IEntityData> rez = new java.util.HashMap<String, IEntityData>();
      if (result != null) {
         for (IEntityData data : result) {
            rez.put(data.getID(), data);
         }
      }
      return rez;
   }

   private void combineSortInfo(RetrieveFilter retrieveFilter, RetrieveParam param) {
      if (param.getNodeSortInfos() != null && param.getNodeSortInfos().size() > 0) {
         for (NodeSortInfo info : param.getNodeSortInfos()) {
            EntityFilter filter = new EntityFilter();
            filter.setSortConditions(info.getSortConditions());
            if (retrieveFilter.getNodeFilters().containsKey(info.getNodeCode())) {
               continue;
            }
            retrieveFilter.getNodeFilters().put(info.getNodeCode(), filter);
         }
      }
   }

   private void addLock(List<String> idList) {
      LockService.getInstance().addLocks(getCurrentBeType(), idList);
   }
}
